#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<netdb.h>
#include<time.h>
#include<fcntl.h>
#include<dirent.h>
#include<getopt.h>
#include<libgen.h>
#include<fcntl.h>
#include<unistd.h>
#include<signal.h>
#include<sqlite3.h>
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/iniparser.h"
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/client_temperature.h"
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/include/mosquitto.h"
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/client_time.h"
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/client_sqlite.h"
#include"/home/xuhuinan1/build/logger/logger.h"
#include"/home/xuhuinan1/ds18b20/mosquitto-2.0.9/platform.h"

//#define       INI_PATH        "/home/xuhuinan1/ds18b20/mosquitto-2.0.9/config.ini"

//#define ID  "h6dxPuvzSD5.MQTT_ds18b20_01|securemode=2,signmethod=hmacsha256,timestamp=1651406942011|"
//#define Username  "MQTT_ds18b20_01&h6dxPuvzSD5"
//#define mqttHostUrl  "iot-06z00bll17yxjgb.mqtt.iothub.aliyuncs.com"
//#define passwd  "1b124cc5a179c3ac20ff44b6e0357cbc9475e22b72a3192fb8325a14b7a762b4"
//#define KEEP_ALIVE 60
//#define PORT  1883
//#define TOPIC  "/sys/h6dxPuvzSD5/MQTT_ds18b20_01/thing/event/property/post"
//#define cjson  {\"method\":\"update\",\"state\": {\"reported\":{\"CurrentTemperature\":\"%.2lf\"}},\"version\":1}


#define MSG_MAX_SIZE 1024//缓冲区最大容量

static int g_stop=0;
bool session=true;
void print_usage(char *progname);
void signal_stop(int signum);//信号

int main(int argc,char* argv[])
{
        int                     rv;
        sqlite3                 *db;
        struct  mosquitto       *mosq=NULL;
        char                    buff[MSG_MAX_SIZE];
        char                    buf[MSG_MAX_SIZE];
        int                     socket_fd=-1;
        int                     opt;
        int                     daemon_run=0;
        char                    *get_ip;
        struct hostent          *get_host;
        float                   temperature;
        int                     log_fd;
        int                     stop_time=30;
        char                    T_time[64];
        char                    *clientid;
        char                    *hostname;
        char                    *username;
        char                    *topic;
        char                    *password;
        char                    *js;
        char                    *name;
        int                     keepalive;
        const char              *str;
        int                     port;
        char                    *platform;

         //platform=(char*)malloc(100*sizeof(char));


        /*命令行参数*/
        struct option   opts[]={
                {"daemon",no_argument,NULL,'d'},
                {"help", no_argument, NULL, 'H'},
                {"ip", required_argument, NULL,'i'},
                {"topic", required_argument, NULL,'t'},
                {"hostname", required_argument, NULL,'n'},
                {"port", required_argument, NULL,'p'},
                {"clientId", required_argument, NULL,'c'},
                {"username", required_argument, NULL,'u'},
                {"password", required_argument, NULL,'w'},
                {"keepalive",required_argument,NULL,'k'},
                {"aliyun",required_argument,NULL,'A'},
                {"huaweiyun",required_argument,NULL,'H'},
                {"tencentyun",required_argument,NULL,'T'},
                {NULL,0,NULL,0},
        };

        while((opt=getopt_long(argc,argv,"dhi:t:n:p:c:u:w:k:A:H:T:",opts,NULL))!=-1)
        {
                switch(opt)
                {

                        case'd':
                                daemon_run=1;
                                break;
                        case 'h':
                                print_usage(argv[0]);
                                return 0;
                        case 'i':
                                get_ip = optarg;
                                break;
                        case 't':
                                topic = optarg;
                                break;

                        case 'n':
                                hostname = optarg;
                                break;

                        case 'p':
                                port = atoi(optarg);
                                break;

                        case 'c':
                                clientid = optarg;
                                break;

                        case 'u':
                                username = optarg;
                                break;

                        case 'w':
                                password = optarg;
                                break;
                        case 'k':
                                keepalive = atoi(optarg);
                                break;
                        case 'A':
                                platform=optarg;
                                //strncpy(platform,"ali",100);
                                break;
                        case 'H':
                                platform=optarg;
                                //strncpy(platform,"huawei",100);
                                break;
                        case 'T':
                                platform=optarg;
                                //strncpy(platform,"tencent",100);
                                break;
                        default:
                                break;

                }
        }

        printf("%s\n",platform);
        platform_ctr(platform,clientid,hostname, username,topic,name,js,password,keepalive,port);

        /*域名解析*/
        if(hostname){
                printf("hostname=%s\n",hostname);
                get_host = gethostbyname(hostname);
                if(!get_host)
                {
                        printf("gethostbyname() get ip failure:%s\n", strerror(errno));
                        rv = -1;
                }

                get_ip = inet_ntoa(*(struct in_addr *)get_host->h_addr);
                printf("DNS ip is:%s\n", get_ip);
        }
        if(!port&&(!hostname||!get_ip)&&(!platform)){
                print_usage(argv[0]);
                return 0;
        }

        /*日志*/
        if( logger_init("temperature.log", LOG_LEVEL_DEBUG) < 0){
                fprintf(stderr, "initial logger system failure\n");
                return 2;
        }

        /*后台运行*/
        if(daemon_run){
                /*设置守护进程*/
                if ((daemon(1, 1)) < 0){
                        //printf("Deamon failure : %s\n", strerror(errno));
                        log_error("This is error level message!");
                        return 0;
                }
                printf("Program %s is running at the background now\n", argv[0]);
        }

        /*mosquitto库初始化*/
        rv=mosquitto_lib_init();
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("mosquitto init failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        else{
                printf("mosquitto init successful\n");
        }

        /*创建一个新的客户实例*/
        mosq=mosquitto_new(clientid,session,NULL);

        if(!mosq){
                printf("new pub_test failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        else{
                printf("create mosquitto successful\n");
        }

        /*在连接服务器之前配置用户名和密码*/
        rv=mosquitto_username_pw_set(mosq,username,password);
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("set username and password failure:%s\n",strerror(errno));
                mosquitto_destroy(mosq);
                mosquitto_lib_cleanup();
        }
        /*打开数据库*/
        rv=sqlite3_open("/home/xuhuinan1/ds18b20/mosquitto-2.0.9/temper.db",&db);
        if(rv!=SQLITE_OK)
                {

                        printf("open database failure:%s\n",strerror(errno));
                        sqlite3_close(db);

                }
        else
                {
                        printf("open database successful\n");
                        sqlite_create(db);
                }
        /*连接服务器*/
         rv=mosquitto_connect(mosq,get_ip,port,keepalive);
                if(rv!=MOSQ_ERR_SUCCESS){
                        printf("mosquitto_connect failure:%s\n",strerror(errno));
                        mosquitto_destroy(mosq);
                        mosquitto_lib_cleanup();
                        sqlite_insert(db,buf);
                }
                else{
                        printf("mosquitto_connect successfully\n");
                        /*创建新的线程循环处理*/
                        rv=mosquitto_loop_start(mosq);
                        if(rv!=MOSQ_ERR_SUCCESS){
                                printf("mosquitto_loop failure:%s\n",strerror(errno));
                                mosquitto_destroy(mosq);
                                mosquitto_lib_cleanup();
                        }
                        printf("loop ok!\n");
        signal(SIGTERM,signal_stop);
        signal(SIGPIPE,signal_stop);


        while(!g_stop){
                //获取采样温度
                get_temperature(&temperature);
                if(temperature<0)
                {
                        printf("read temperature failure:%s\n",strerror(errno));
                        return -1;
                }
                else
                {
                        printf("read temperature %f successful\n",temperature);
                        snprintf(buff,sizeof(buff),js,temperature);
                }
                printf("%s\n",buff);
                //获取采样时间
                get_time(T_time,sizeof(T_time));
                if(T_time<0)
                {
                        printf("get time  failure:%s\n",strerror(errno));
                        return -1;
                }
                else
                {
                        printf("get time successful\n");
                }
                snprintf(buf,sizeof(buf),"%s/%s/%f",name,T_time,temperature);
                //上报
                rv=mosquitto_publish(mosq,NULL,topic,strlen(buff)+1,buff,0,0);
                        if(rv!=MOSQ_ERR_SUCCESS){
                                printf("mosquitto_publish failure:%s\n",strerror(errno));
                                mosquitto_destroy(mosq);
                                mosquitto_lib_cleanup();
                        }
                        printf("publish information ok!\n");
                        sqlite_insert(db,buf);
                        sleep(stop_time);
                }
        sqlite3_close(db);

        }
}



void print_usage(char *progname)
{
        printf("%s usage: \n", progname);
        printf("-i(--ip): ip address.\n");
        printf("-d(--daemon): run background.\n");
        printf("-t(--topic):  MQTT topic.\n");
        printf("-n(--hostname): server domain name.\n");
        printf("-p(--port):  server port.\n");
        printf("-c(--clientid): specify clientid.\n");
        printf("-u(--username): specify username.\n");
        printf("-w(--password): specify user password.\n");
        printf("-k(--keepalive):The heartbeat packets.\n");
        printf("-h(--Help): print this help information.\n");
        printf("-A(--ali platform)\n");
        printf("-H(--huawei platform)\n");
        printf("T(--tencent platform)\n");

        return ;
}

void signal_stop(int signum)
{
        if(SIGTERM==signum)
        {
                printf("SIGTERM signal detected\n");
                g_stop=1;
        }
        else if(SIGPIPE==signum)
        {

                printf("SIGPTPE signal detected\n");
        }
}
